package cn.kgc.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author YC
 * 自定义HTTP请求处理器
 * 继承SimpleChannelInboundHandler<I> 泛型指定为HttpObject，表示处理HTTP相关的对象
 */
@Slf4j
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {

    /**
     * 当通道有读取事件时会触发此方法
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject httpObject) throws Exception {
        // 判断msg是否是HttpRequest对象
        if (httpObject instanceof HttpRequest) {
            HttpRequest httpRequest = (HttpRequest) httpObject;
            Channel channel = ctx.channel();
            // 打印请求信息
            log.debug("收到请求,请求IP地址: {},请求方法名: {},请求URI: {},请求协议版本: {}",
                    channel.remoteAddress(), httpRequest.method().name(), httpRequest.uri(), httpRequest.protocolVersion());
            // 构建响应内容
            ByteBuf byteBuf = Unpooled.copiedBuffer("Hello, this is Netty HTTP Server!", CharsetUtil.UTF_8);
            // 构建HTTP响应对象
            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    byteBuf
            );
            // 设置响应头
            response.headers()
                    .set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8")
                    .set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
            // 如果是长连接，设置相应的头信息
            if (HttpUtil.isKeepAlive(httpRequest)) {
                response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            }
            // 发送响应
            ctx.writeAndFlush(response);
            // 如果不是长连接，发送完响应后关闭通道
            if (!HttpUtil.isKeepAlive(httpRequest)) {
                ctx.channel().close();
            }
        }
    }

    /**
     * 当通道激活时触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("客户端连接成功: {}", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    /**
     * 当通道关闭时触发
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.debug("客户端断开连接: {}", ctx.channel().remoteAddress());
        super.channelInactive(ctx);
    }

    /**
     * 发生异常时触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.debug("发生异常: {}", cause.getMessage());
        // 发生异常时关闭通道
        ctx.close();
    }

}
